﻿using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace Ooaavee.Data.Model
{
    /// <summary>
    /// A database table or view.
    /// </summary>
    [DataContract]
    [DebuggerDisplay("{DebuggerDisplay,nq}")]
    public sealed class Table
    {
        /// <summary>
        /// Table type: system table.
        /// </summary>
        public const string TableTypeSystemTable = "SYSTEM TABLE";

        /// <summary>
        /// Table type: system view.
        /// </summary>
        public const string TableTypeSystemView = "SYSTEM VIEW";

        /// <summary>
        /// Table type: user table.
        /// </summary>
        public const string TableTypeUserTable = "TABLE";

        /// <summary>
        /// Table type: user view.
        /// </summary>
        public const string TableTypeUserView = "VIEW";

        [DataMember]
        private readonly ColumnCollection _columns = new ColumnCollection();

        /// <summary>
        /// The relational model.
        /// </summary>
        [DataMember]
        public RelationalModel Parent { set; get; }

        /// <summary>
        /// Table catalog.
        /// </summary>
        [DataMember]
        public string Catalog { set; get; }

        /// <summary>
        /// Table schema.
        /// </summary>
        [DataMember]
        public string Schema { set; get; }

        /// <summary>
        /// Table name.
        /// </summary>
        [DataMember]
        public string Name { set; get; }

        /// <summary>
        /// Table type.
        /// </summary>
        [DataMember]
        public string TableType { set; get; }

        /// <summary>
        /// All columns.
        /// </summary>
        public ColumnCollection Columns { get { return _columns; } }

        /// <summary>
        /// Checks if the Table matches the specified name.
        /// </summary>
        /// <param name="name">The String containing the name of the table.</param>
        /// <returns>true/false</returns>
        internal bool MatchByName(string name)
        {
            var tokens = name.Split('.');

            switch (tokens.Length)
            {
                case 1:
                    return string.Equals(tokens[0], Name, StringComparison.CurrentCultureIgnoreCase);
                case 2:
                    return string.Equals(tokens[0], Schema, StringComparison.CurrentCultureIgnoreCase) &&
                           string.Equals(tokens[1], Name, StringComparison.CurrentCultureIgnoreCase);
                case 3:
                    return string.Equals(tokens[0], Catalog, StringComparison.CurrentCultureIgnoreCase) &&
                           string.Equals(tokens[1], Schema, StringComparison.CurrentCultureIgnoreCase) &&
                           string.Equals(tokens[2], Name, StringComparison.CurrentCultureIgnoreCase);
                default:
                    return false;
            }
        }

        #region Debugger
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "See DebuggerDisplayAttribute marked on this class.")]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string DebuggerDisplay { get { return string.Format("{0}.{1}.{2}", Catalog, Schema, Name); } }
        #endregion
    }
}
